import 'dart:convert';
import 'dart:typed_data';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:common_utils/common_utils.dart';
import 'package:karyo/karyo.dart';
import 'package:meta/meta.dart';
import 'package:flutter/material.dart';

class Session {
  Session(
      {@required this.targetAvatar,
      @required this.targetName,
      @required this.lastMsg,
      @required this.lastTime,
      @required this.isMute,
      @required this.targetAddr,
      this.sender,
      this.lastTimeStamp,
      this.senderName,
      this.sessionId,
      this.targetGenderIndex,
      this.targetAvatarImage,
      this.sessionUID,
      this.groupAddr,
      this.groupMembersNum,
      this.groupOwnerAddr,
      this.sessionType,
      this.userLevel,
      this.chatMembers,
      this.targetUser,
      this.accountType});

  int sessionId;
  String sessionUID;
  final String targetAvatar;
  final String targetName;

  // final String groupAvatarUrl;
  // final String groupName;
  // final
  int groupMembersNum;
  final String groupAddr;
  final String lastMsg;
  final String lastTime;
  final int lastTimeStamp;
  final bool isMute;
  final String targetAddr;
  String groupOwnerAddr;
  int targetGenderIndex;
  String sender;
  String senderName;
  // the new coming msgs
  int newMsgNum = 0;
  int sessionType;

  int userLevel;
  int accountType;
  ImageProvider targetAvatarImage;

  List<User> chatMembers;
  User targetUser;

  static List<Session> allFromResponse(String response) {
    var decodedJson = json.decode(response);
    if (decodedJson['code'] == 403 || decodedJson['code'] == 400) {
      // token invalid or request invalid
      return null;
    } else {
      return decodedJson['data']
          .cast<Map<String, dynamic>>()
          .map((obj) => Session.fromMap(obj))
          .toList()
          .cast<Session>();
    }
  }

  static Session fromMap(Map map) {
    var lastTime = map['last_time'];
    var sessionType = map['session_type'];

    // format last_time into human readable format
    var _tStamp = DateTime.parse(lastTime).toLocal().millisecondsSinceEpoch;
    var t = TimelineUtil.format(_tStamp);
    var genderIndex = 0;
    ImageProvider targetAvatarImage;

    // get chat members
    List<User> _chatMembers = [];
    for (var m in map['chat_members']) {
      var _u = User.fromMap(m);
      // if (!(sessionType == 0 && _u.userAddr == map['sender'])) {
      _chatMembers.add(_u);
      // }
    }

    if (sessionType == null) {
      sessionType = 0;
    }
    if (sessionType == 0) {
      // user session, could be null
      var targetUser = map['target_user'];
      if (targetUser != null) {
        var targetUserAvatarUrl = targetUser['user_avatar_url'];
        if (targetUser['user_gender'] != null &&
            targetUser['user_gender'] != '' &&
            targetUser['user_gender'] != 'null') {
          genderIndex = int.parse(targetUser['user_gender']);
        }
        if (targetUserAvatarUrl != null && targetUserAvatarUrl != '') {
          // targetAvatarImage = AdvancedNetworkImage(targetUserAvatarUrl);
          targetAvatarImage = CachedNetworkImageProvider(
            API.BASE_URL + targetUserAvatarUrl,
          );
        } else if (targetUser['user_avatar'] != null &&
            targetUser['user_avatar'] != '') {
          Uint8List bytes = base64.decode(targetUser['user_avatar']);
          targetAvatarImage = MemoryImage(bytes);
        } else {
          targetAvatarImage = AssetImage('assets/images/blank_avatar.png');
        }

        return new Session(
            sessionUID: map['session_uid'],
            sessionId: map['session_id'],
            targetAvatar: targetUser['user_avatar'],
            targetGenderIndex: genderIndex,
            targetName: map['target_name'],
            lastMsg: map['last_msg'],
            lastTime: t,
            lastTimeStamp: _tStamp,
            isMute: false,
            targetAddr: map['target'],
            sender: map['sender'],
            senderName: map['senderName'],
            targetAvatarImage: targetAvatarImage,
            sessionType: sessionType,
            userLevel: targetUser['user_level'],
            chatMembers: _chatMembers,
            targetUser: User.fromMap(targetUser),
            accountType: targetUser['account_type']);
      } else {
        targetAvatarImage = AssetImage('assets/images/blank_avatar.png');
        targetUser = User(
            userAcc: 'unknow',
            userNickName: 'unknow',
            userAvatarUrl: '',
            userAddr: map['target']);
        return new Session(
            sessionUID: map['session_uid'],
            sessionId: map['session_id'],
            targetAvatar: null,
            targetGenderIndex: 0,
            targetName: map['target_name'] + '[已注销]',
            lastMsg: map['last_msg'],
            lastTime: t,
            lastTimeStamp: _tStamp,
            isMute: false,
            targetAddr: map['target'],
            sender: map['sender'],
            senderName: map['senderName'],
            targetAvatarImage: targetAvatarImage,
            sessionType: sessionType,
            userLevel: map['user_level'],
            chatMembers: _chatMembers,
            targetUser: targetUser,
            accountType: map['account_type']);
      }
    } else if (sessionType == 1) {
      // for group
      var targetGroup = map['target_group'];
      if (targetGroup['group_avatar_url'] != null &&
          targetGroup['group_avatar_url'] != '') {
        // targetAvatarImage = AdvancedNetworkImage(baseUrl + targetUser['group_avatar_url']);
        targetAvatarImage = CachedNetworkImageProvider(
          API.BASE_URL + targetGroup['group_avatar_url'],
        );
      } else {
        // print('----------- using assets');
        targetAvatarImage = AssetImage('assets/images/blank_avatar.png');
      }
      var targetUser = User(
          userAcc: 'unknow',
          userNickName: targetGroup['group_name'],
          userAvatarUrl: '',
          userAddr: targetGroup['group_addr']);
      return new Session(
          sessionUID: map['session_uid'],
          sessionId: map['session_id'],
          targetAvatar: "",
          targetGenderIndex: 4,
          targetName: targetGroup['group_name'],
          groupAddr: targetGroup['group_addr'],
          groupMembersNum: targetGroup["group_members_num"],
          groupOwnerAddr: targetGroup['group_creator_addr'],
          lastMsg: map['last_msg'],
          lastTime: t,
          lastTimeStamp: _tStamp,
          isMute: false,
          targetUser: targetUser,
          targetAddr: map['group_addr'],
          sender: map['sender'],
          senderName: map['senderName'],
          targetAvatarImage: targetAvatarImage,
          chatMembers: _chatMembers,
          sessionType: sessionType);
    }
  }
}
